package ueb15;


import java.awt.Color;

import ueb15.NodeImpl;

/**
 * Allows us to notice changes.
 */
public class PaintableNodeImpl extends NodeImpl {

	private final PaintableRedBlackTreeImpl tree;

	public PaintableNodeImpl(PaintableNodeImpl node, PaintableRedBlackTreeImpl tree) {
		super(node);
		this.tree = tree;
	}

	public PaintableNodeImpl(PaintableRedBlackTreeImpl tree) {
		super(null);
		this.tree = tree;
	}

	public Color getColor() {
		if (isBlack()) {
			return Color.BLACK;
		} else {
			return Color.RED;
		}
	}

	@Override
	public PaintableNodeImpl getLeftChild() {
		NodeImpl result = super.getLeftChild();
		if (result == null || result instanceof PaintableNodeImpl) {
			return (PaintableNodeImpl) result;
		}
		throw new IllegalStateException("Something went wrong.  Please use 'RedBlackTree.createNode' instead of 'new NodeImpl'.");
	}

	@Override
	public PaintableNodeImpl getRightChild() {
		NodeImpl result = super.getRightChild();
		if (result == null || result instanceof PaintableNodeImpl) {
			return (PaintableNodeImpl) result;
		}
		throw new IllegalStateException("Something went wrong.  Please use 'RedBlackTree.createNode' instead of 'new NodeImpl'.");
	}

	@Override
	protected void makeBlack() {
		super.makeBlack();
		updateGui();
	}

	@Override
	protected void makeRed() {
		super.makeRed();
		updateGui();
	}

	@Override
	protected void setLeftChild(NodeImpl leftChild) {
		validatePaintableNode(leftChild);
		super.setLeftChild(leftChild);
		updateGui();
	}

	@Override
	protected void setParent(NodeImpl parent) {
		validatePaintableNode(parent);
		super.setParent(parent);
		updateGui();
	}

	@Override
	protected void setRightChild(NodeImpl rightChild) {
		validatePaintableNode(rightChild);
		super.setRightChild(rightChild);
		updateGui();
	}

	@Override
	public void setiData(Object value) {
		if (value == null) {
			throw new IllegalArgumentException("Cannot insert a null value into the tree!");
		}
		super.setiData(value);
		updateGui();
	}

	private void updateGui() {
		if (tree.getControler() != null) {
			tree.getControler().updateGui();
		}
	}

	private void validatePaintableNode(NodeImpl nodeI) {
		if (nodeI != null && !(nodeI instanceof PaintableNodeImpl)) {
			throw new IllegalArgumentException("Given node was from a different tree!");
		}
	}

}
